home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.04 Apr 96 / ThreadingAppleEvents.sit / ThreadingAppleEvents / Grant's CGI Code 1.0b13 / Startup / Startup.c / Startup.c
Encoding:
C/C++ Source or Header  |  1996-01-26  |  11.2 KB  |  509 lines  |  [TEXT/CWIE]

  1. /*****
  2.  *
  3.  *    Startup.c
  4.  *
  5.  *    If you want to exclude CGI or ListSTAR support, remove the appropriate lines
  6.  *    from the 'StartupApplication' function.
  7.  *
  8.  *    This is a support file for "Grant's CGI Framework".
  9.  *    Please see the license agreement that accompanies the distribution package
  10.  *    for licensing details.
  11.  *
  12.  *    Copyright ©1995 by Grant Neufeld
  13.  *    grant@acm.com
  14.  *    http://arpp1.carleton.ca/grant/
  15.  *
  16.  *****/
  17.  
  18. #include "MyConfiguration.h"
  19.  
  20. #include <Threads.h>
  21. #include <Traps.h>
  22.  
  23. #include "compiler_stuff.h"
  24. #include "constants.h"
  25. #include "globals.h"
  26.  
  27. #include "AboutBox.h"
  28. #include "AEFunc.h"
  29. #include "AEHandlers.h"
  30. #include "CGI.h"
  31. #include "ErrorUtil.h"
  32. #include "EventUtil.h"
  33. #include "ListSTAR.h"
  34. #include "MemoryUtil.h"
  35. #include "MenuFunc.h"
  36. #include "ProcessUtil.h"
  37. #include "SplashScreen.h"
  38. #include "StringUtil.h"
  39. #include "Version.h"
  40.  
  41. #include "Startup.h"
  42.  
  43.  
  44. /***  LOCAL CONSTANTS ***/
  45.  
  46. #define    TrapMask        0x0800
  47. #define kGestaltMask    1L
  48.  
  49. /* window info */
  50. #define    kScreenBorder    4    /* pixels */
  51. #define    kIconSize        32
  52.  
  53.  
  54. /***  LOCAL PROTOTYPES ***/
  55.  
  56. static    void        startupErrors            ( void );
  57. static    void        startupGestalt            ( void );
  58. static    void        startupEvent            ( void );
  59. static    void        startupAE                ( void );
  60. static    void        startupThreads            ( void );
  61. #if kCompileWithForeground
  62. static    void        startupMenus             ( void );
  63. static    void        startupWindows            ( void );
  64. static    void        startupQuickDraw        ( void );
  65. #if kCompileWithDragNDrop
  66. static    void        startupDrag                ( void );
  67. #endif
  68.  
  69. #else
  70.     /* make the interface function prototypes null */
  71.     #define startupMenus()    
  72.     #define startupWindows()    
  73.     #define startupQuickDraw()    
  74. #endif    /* kCompileWithForeground */
  75.     
  76. static    Boolean        startupTrapAvailable    ( unsigned long );
  77. static    TrapType    startupTrapType            ( unsigned long );
  78.  
  79.  
  80. /***  FUNCTIONS  ***/
  81.  
  82. void
  83. StartupApplication ( void )
  84. {
  85.     OSErr    theErr;
  86.     
  87.     gSleepTicks        = kSleepTicks;
  88.     gFrontProcess    = ProcessCurrentIsFront ();
  89.     
  90.     #if kCompileWithProcessFileSpec
  91.     ProcessGetMyFSSpec ( &gProcessFSSpec );
  92.     #endif
  93.     
  94.     startupErrors        ();
  95.     
  96.     VersionGetShort        ( 1, gVersionStr );    /* must be before splash screen */
  97.     
  98.     SplashScreenCreate    ();    /* put up splash screen */
  99.  
  100.     startupGestalt        ();    /* must be before all Manager inits except toolbox and memory */
  101.     startupEvent        ();
  102.     startupAE            ();
  103.     startupMenus        ();
  104.     startupThreads        ();
  105.     startupWindows        ();    /* must be after startupMenus */
  106.     startupQuickDraw    ();
  107.     #if kCompileWithDragNDrop
  108.     startupDrag            ();
  109.     #endif
  110.     AboutBoxInit        ();
  111.     
  112.     #if kCompileWithQuitOnLongIdle
  113.     gDoIdleQuit        = true;    /* quit after given period of idle time */
  114.     gTimeLastAction = nil;    /* no action has been performed yet */
  115.     gIdleTimeToQuit    = kIdleTimeToQuit;
  116.     gDoIdleQuitOnOpenApp    = kCompileWithIdleQuitOnOpenApp;
  117.     #endif
  118.     
  119.     theErr = InitCGIUtil ();    /* CGI Specific */
  120.     if ( theErr != noErr )
  121.     {
  122.         ErrorStartup ( kerrStartupCGI );
  123.     }
  124.     
  125.     theErr = InitListSTARUtil ();    /* ListSTAR Specific */
  126.     if ( theErr != noErr )
  127.     {
  128.         ErrorStartup ( kerrStartupListSTAR );
  129.     }
  130.     
  131.     /* • the result of this call should be checked to see whether
  132.         initialization was successful */
  133.     theErr = MyStartup ();
  134.     if ( theErr != noErr )
  135.     {
  136.         ErrorStartup ( kerrStartupCustomInit );
  137.     }
  138.     
  139. // • moved to "MyHandlers.c"
  140. //    MyCGIStartup        ();    /* CGI Specific */
  141. //    MyListSTARStartup    ();    /* ListSTAR Specific */
  142.     
  143.     SplashScreenDispose ();    /* remove splash screen */
  144. } /* StartupApplication */
  145.  
  146.  
  147. /***  Initialization Functions  ***/
  148. #pragma mark -
  149.  
  150. /* Initialize default string for system errors */
  151. static void
  152. startupErrors ( void )
  153. {
  154.     StringHandle    tempStr;
  155.     
  156.     /* set system error default string */
  157.     
  158.     gSystemErrorStr    = (StringHandle) MyNewHandle ( sizeof(Str255), nil );
  159.     
  160.     if ( gSystemErrorStr == nil )
  161.     {
  162.         return;
  163.     }
  164.     
  165.     HLockHi ( (Handle)gSystemErrorStr );
  166.     
  167.     tempStr = GetString ( krErrSystemDefault );
  168.     
  169.     if ( tempStr == nil )
  170.     {
  171.         StringPascalCopy ( (char *)ksErrSystemDefault, (char *)(*gSystemErrorStr) );
  172.     }
  173.     else
  174.     {
  175.         HLock ( (Handle)tempStr );
  176.         
  177.         StringPascalCopy ( (char *)(*tempStr), (char *)(*gSystemErrorStr) );
  178.         
  179.         HUnlock            ( (Handle)tempStr );
  180.         ReleaseResource    ( (Handle)tempStr );
  181.     }
  182.     
  183.     HUnlock ( (Handle)gSystemErrorStr );
  184. } /* startupErrors */
  185.  
  186.  
  187. /* Determine if the Gestalt manager is available */
  188. static void
  189. startupGestalt ( void )
  190. {
  191.     Boolean        gestaltAvail;
  192.     
  193.     /* determine whether the Gestalt call is available */
  194.     gestaltAvail = startupTrapAvailable ( _Gestalt );
  195.     
  196.     if ( !gestaltAvail )
  197.     {
  198.         /* Gestalt require for application to work, inform the user and exit */
  199.         ErrorStartup ( kerrStartupGestalt );
  200.     }
  201. } /* startupGestalt */
  202.  
  203.  
  204. /* Determine if WaitNextEvent trap is available. */
  205. static void
  206. startupEvent ( void )
  207. {
  208.     OSErr        theErr;
  209.     SysEnvRec    theSysEnv;    /* system environment */
  210.     Boolean        WNEAvail;
  211.     
  212.     /* what are we running on here (System 4.1 or greater) */
  213.     theErr = SysEnvirons ( 1, &theSysEnv );
  214.     
  215.     if ( theErr != noErr )
  216.     {
  217.         /* can't figure out what the system environment is, inform the user and exit */
  218.         ErrorStartup ( kerrStartupSysEnv );
  219.     }
  220.     else
  221.     {
  222.         /* is WaitNextEvent implemented? - from Macintosh Tech Note #158 */
  223.         if ( theSysEnv.machineType > envMachUnknown )
  224.         {
  225.             WNEAvail = NGetTrapAddress(0x60, ToolTrap) != NGetTrapAddress(0x9F, ToolTrap);
  226.         }
  227.         else
  228.         {
  229.             WNEAvail = false;
  230.         }
  231.     }
  232.     
  233.     if ( !WNEAvail )
  234.     {
  235.         /* WaitNextEvent trap is missing - can't run */
  236.         ErrorStartup ( kerrStartupWNE );
  237.     }
  238. } /* startupEvent */
  239.  
  240.  
  241. /* Determine if Apple Event Manager is present and install handlers */
  242. static void
  243. startupAE ( void )
  244. {
  245.     long    feature;
  246.     OSErr    theErr;
  247.     
  248.     theErr = Gestalt ( gestaltAppleEventsAttr, &feature );
  249.     if ( (theErr != noErr) ||
  250.         !(feature & (kGestaltMask << gestaltAppleEventsPresent)) )
  251.     {
  252.         /* Apple Events not available, inform the user and exit */
  253.         ErrorStartup ( kerrStartupAppleEvent );
  254.     }
  255.  
  256.     gAEIdleUPP = NewAEIdleProc ( MyAEIdleFunc );
  257.     
  258.     theErr = AEInstallHandlers ();
  259.     if ( theErr != noErr )
  260.     {
  261.         ErrorSystem ( theErr );
  262.     }
  263.     
  264. //    theErr = EventSpawnAEDispatcherThread ();
  265. } /* startupAE */
  266.  
  267.  
  268. /* setup menus */
  269. #if kCompileWithForeground
  270. static void
  271. startupMenus ( void )
  272. {
  273.     Handle            theMenuBar;
  274.     
  275.     theMenuBar = GetNewMBar ( kmMenuBarID );
  276.     
  277.     if ( theMenuBar == nil )
  278.     {
  279.         /* can't load menu bar */
  280.         ErrorStartup ( kerrStartupMenu );
  281.     }
  282.     
  283.     SetMenuBar ( theMenuBar );
  284.  
  285.     gmAppleMenu    = GetMHandle ( kmAppleMenuID );
  286.     /* add "Apple Menu Items" to the Apple menu */
  287.     AddResMenu    ( gmAppleMenu, 'DRVR' );
  288.  
  289.     gmFileMenu    = GetMHandle ( kmFileMenuID );
  290.     gmEditMenu    = GetMHandle ( kmEditMenuID );
  291.     
  292.     DrawMenuBar ();
  293. } /* startupMenus */
  294. #endif    /* kCompileWithForeground */
  295.  
  296.  
  297. /* determine if thread manager is available */
  298. static void
  299. startupThreads ( void )
  300. {
  301.     OSErr    theErr;
  302.     long    feature;
  303.     
  304.     #if kCompileWithThreadsOptional
  305.     gHasThreadMgr = false;
  306.     #endif
  307.     
  308.     theErr = Gestalt ( gestaltThreadMgrAttr, &feature );
  309.     
  310.     if ( theErr == noErr )
  311.     {
  312.         if (
  313.             #ifdef powerc
  314.             ( feature & (1 << gestaltThreadsLibraryPresent) ) &&
  315.             /* ••• Can anybody who does PowerPC code tell me why the following
  316.                 line doesn't work?
  317.                 ( (Ptr)NewThread != kUnresolvedSymbolAddress ) &&
  318.                 ••• */
  319.             #endif /* def powerc */
  320.             /* the feature check applies to both 68K & PPC */
  321.             ( feature & (1 << gestaltThreadMgrPresent) ) )
  322.         {
  323.             #if kCompileWithThreadsOptional
  324.             gHasThreadMgr = true;
  325.             #endif
  326.             
  327.             /* no sub threads running yet */
  328.             #if kStartupThreadsPreallocate > nil
  329.             gThreadTotal = nil;
  330.             /* no sleeping thread yet */
  331. //            gThreadSleeperIndex = 0;
  332.             gThreadSleeper = nil;
  333.             #endif
  334.             
  335.             /* determine the id of the main (current) thread */
  336.             GetCurrentThread ( &gThreadMain );
  337.             
  338.             #if kStartupThreadsPreallocate > nil
  339.             /* pre-allocate the required number of threads */
  340.             CreateThreadPool ( kCooperativeThread, kStartupThreadsPreallocate, nil );
  341.             #endif
  342.         }
  343.     }
  344. } /* startupThreads */
  345.  
  346.  
  347. /* Determine the space available on the main and other monitors */
  348. #if kCompileWithForeground
  349. static void
  350. startupWindows ( void )
  351. {
  352.     short         resW;
  353.     short        resH;
  354.     short        menuBarHeight;
  355.     RgnHandle    grayRgnHdl;
  356.     Rect        grayRgnBounds;
  357.     
  358.     /* get screen dimensions */
  359.     resW = qd.screenBits.bounds.right  - qd.screenBits.bounds.left;
  360.     resH = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
  361.     
  362.     menuBarHeight = LMGetMBarHeight ();
  363.     
  364.     /* gScreenRect is the size of the main screen, inset by a margin */
  365.     SetRect ( &gScreenRect, kScreenBorder, menuBarHeight + kScreenBorder, 
  366.         resW - kScreenBorder, resH - kScreenBorder );
  367.         
  368.     /* get entire gray rgn rect (the size of all monitors) */
  369.     grayRgnHdl        = GetGrayRgn ();            /* known as the 'gray region' */
  370.     grayRgnBounds    = (*grayRgnHdl)->rgnBBox;    /* the bounding box for the region */
  371.     
  372.     resW = grayRgnBounds.right  - grayRgnBounds.left;
  373.     resH = grayRgnBounds.bottom - grayRgnBounds.top;
  374.     
  375.     /* this rect encompasses all of the monitor desktop space,
  376.         minus the menu bar and inset by a margin. We'll use this
  377.         rectangle to limit dragging and resizing windows */
  378.     SetRect ( &gGrayRgnRect,
  379.         /* left */        kScreenBorder,
  380.         /* top */        menuBarHeight + kScreenBorder, 
  381.         /* right */        resW - kScreenBorder,
  382.         /* bottom */    resH - kScreenBorder );
  383. } /* startupWindows */
  384. #endif    /* kCompileWithForeground */
  385.  
  386.  
  387. /* QuickDraw - Graphics */
  388. #if kCompileWithForeground
  389. static void
  390. startupQuickDraw ( void )
  391. {
  392.     OSErr    theErr;
  393.     long    feature;
  394.     long    version;
  395.     
  396.     gHasColorQD = false;
  397.     
  398.     theErr = Gestalt ( gestaltQuickdrawFeatures, &feature );
  399.     
  400.     if ( theErr == noErr )
  401.     {
  402.         theErr = Gestalt ( gestaltQuickdrawVersion, &version );
  403.     }
  404.     
  405.     if ( (theErr == noErr) &&
  406.         ((feature & (kGestaltMask << gestaltHasColor)) != nil) &&
  407.         (version >= gestalt8BitQD) )
  408.     {
  409.         gHasColorQD = true;
  410.     }
  411. } /* startupQuickDraw */
  412. #endif    /* kCompileWithForeground */
  413.  
  414.  
  415. /* Drag Manager - interapplication drag'n'drop */
  416. #if kCompileWithDragNDrop
  417. static void
  418. startupDrag ( void )
  419. {
  420.     long    feature;
  421.     OSErr    theErr;
  422.     
  423.     theErr = Gestalt ( gestaltDragMgrAttr, &feature );
  424.     
  425.     if ( (theErr == noErr) &&
  426.         (feature & (kGestaltMask << gestaltDragMgrPresent)) )
  427.     {
  428.         gHasDragNDrop = true;
  429.     }
  430.     else
  431.     {
  432.         gHasDragNDrop = false;
  433.     }
  434. } /* startupAE */
  435. #endif
  436.  
  437.  
  438. #pragma mark -
  439.  
  440. /* Determine if a trap is available */
  441. static Boolean
  442. startupTrapAvailable ( unsigned long trap )
  443. {
  444.     UniversalProcPtr    theInitGrafAddr;
  445.     UniversalProcPtr    theAA6EAddr;
  446.     Boolean                trapAddrMatch;
  447.     unsigned long        numToolBoxTraps;
  448.     TrapType            theTrapType;
  449.     unsigned long        theTrapMasked;
  450.     
  451.     theInitGrafAddr    = NGetTrapAddress ( _InitGraf, ToolTrap );
  452.     theAA6EAddr        = NGetTrapAddress ( 0xAA6E, ToolTrap );
  453.     trapAddrMatch    = theInitGrafAddr == theAA6EAddr;
  454.     
  455.     if ( trapAddrMatch )
  456.     {
  457.         numToolBoxTraps = 0x200;
  458.     }
  459.     else
  460.     {
  461.         numToolBoxTraps = 0x400;
  462.     }
  463.     
  464.     theTrapType = startupTrapType ( trap );
  465.     if ( theTrapType == ToolTrap )
  466.     {
  467.         theTrapMasked = trap & 0x07FF;
  468.         if ( theTrapMasked >= numToolBoxTraps )
  469.         {
  470.             return false;
  471.         }
  472.     }
  473.     
  474.     return NGetTrapAddress ( _Unimplemented, ToolTrap ) !=
  475.             NGetTrapAddress ( trap, theTrapType );
  476.     
  477. //    if ( theTrapType == ToolTrap )
  478. //    {
  479. //        theTrapMasked = trap & 0x07FF;    /* mask off bits from trap */
  480.         
  481. //        if ( theTrapMasked >= numToolBoxTraps )
  482. //        {
  483. //            theTrapMasked = _Unimplemented;
  484. //        }
  485. //    }
  486.     
  487. //    return ( NGetTrapAddress(theTrapMasked, theTrapType)
  488. //        != NGetTrapAddress(_Unimplemented, ToolTrap) );
  489. } /* startupTrapAvailable */
  490.  
  491.  
  492. /* determine the type of the trap */
  493. static TrapType
  494. startupTrapType ( unsigned long theTrap )
  495. {
  496.     /* OS traps start with A0, Tool with A8 or AA. */
  497.     if ( (theTrap & 0x0800) == nil )
  498.     {
  499.         return OSTrap;
  500.     }
  501.     else
  502.     {
  503.         return ToolTrap;
  504.     }
  505. } /* startupTrapType */
  506.  
  507.  
  508. /*****  EOF  *****/
  509.